﻿var $ = window.$;
var input = require('../../../core/input');
var sample = require('../../sample/manager');
var frac = require('../../../util/frac');
var layer = require('../../layer/manager');
var sound = require('../../audio/sound');
var timing = require('../../timing/manager');
var config = require('../../../core/config');
var util = require('../../../util/index');
var vector = require('../vector');
var inherits = require('util').inherits;
var notify = require('../../notify/ui');
var base = require('./edit');

/**
 * 非独立模块, 作为ui的插件
 */

var GridEdit = function () {
    this.MAX_HOLD_NOTES = 2; // 允许连在一起最大的hold note个数
    this.MIN_RAIN_LEN = 1; // 音符雨最小的beat长
    this.currHoldIdx = 0; //当前正在添加第几个hold note
    this.lastNote = null;
};

inherits(GridEdit, base);
GridEdit.prototype._onMouseDown = base.prototype.onMouseDown;
GridEdit.prototype._onMouseMove = base.prototype.onMouseMove;
GridEdit.prototype._onMouseUp = base.prototype.onMouseUp;

GridEdit.prototype.onMouseDown = function(pos, note){
    var e = window.event;
    if((this.intent & this.Intent_Add_Catch_Hold) > 0 || (this.intent & this.Intent_Add_Catch_Rain) > 0){
        //保证第二个点必须在上一个点之前
        var mouseStart = vector.sub([e.pageX, e.pageY], this.ui.offset);
        var posTmp = this.ui.mouseToLayer(mouseStart);
        var gridPos = this.ui.layerToGridOffset(posTmp);
        var tmpBeat = [gridPos[0], gridPos[1], gridPos[2]];
        if(frac.compare(this.lastNote.beat, tmpBeat) != -1){
            this.isMouseDown = false;
            notify.addNotify({msg : config.i18n($("#tool_hold").hasClass("press") ? "catch04" : "catch03")})
            return;
        }
        if((this.intent & this.Intent_Add_Catch_Rain) > 0 && frac.subtract(tmpBeat, this.lastNote.beat)[0] < this.MIN_RAIN_LEN){
            this.isMouseDown = false;
            notify.addNotify({msg : util.formatStr(config.i18n("catch06"), [this.MIN_RAIN_LEN])});
            return;
        }
        //rain里面不允许放note
        if((this.intent & this.Intent_Add_Catch_Rain) > 0){
            if(this.hasNoteInRange(this.lastNote.beat,tmpBeat )){
                notify.addNotify({msg : config.i18n("catch05")})
                return;
            }
        }
    }

	if(!note){
		//如果外部不给note, 就进行一次catch订制的查找
		var _pos = this.ui.mouseToLayer(pos);
		var beat = this.ui.layerToGridOffset(_pos);
		var virtualNote = this.ui.paramToNote(beat);  //当前位置理论上的note
		virtualNote.x = beat[3];
		note = this.ui.manager.findAnyNote(virtualNote);
	}

	this._onMouseDown(pos, note);
	//catch不要key模式的hold, 关掉
	if(this.intent == this.Intent_Change_Hold){
		this.intent = this.Intent_Drag | this.Intent_Select;
	}else if(this.intent == this.Intent_Add_Hold){
		this.intent = this.Intent_Add_Normal | this.Intent_Rect_Select | this.Intent_Cancel_Select;
	}
    //catch专有的hold和rain
    if($("#tool_hold").hasClass("press")){
        this.intent |= this.Intent_Add_Catch_Hold;
    }else if($("#tool_rain").hasClass("press")){
        this.intent |= this.Intent_Add_Catch_Rain;
    }
};

GridEdit.prototype.onMouseMove = function (pos) {
    if (this.intent & this.Intent_Drag) {
        this.intent = this.Intent_Drag; //屏蔽掉其他可性能
        var beat = this.ui.mouseToGridOffset(pos);
        if (!this.data.currBeat) {
            this.data.currBeat = this.data.startBeat;
        }
        if (!vector.equal(beat, this.data.currBeat)) {
            if (!this.data.multiNote) {
                if (this.data.div.hasClass('curr')) {
                    this.data.multiNote = this.ui.note.find('.curr');
                } else {
                    this.data.multiNote = this.data.div;
                }
                this.data.multiArr = [];
                var divs = this.data.multiNote;
                if($("#tool_normal").hasClass("press")){
                    // 成组移动
                    this.ui.clsChainSelect(divs);
                    divs = this.ui.note.children(".chain_select").removeClass("chain_select");
                    this.data.multiNote = divs;
                }
                for (var i = 0; i < divs.size(); i++) {
                    var obj = divs.eq(i);
                    var offset = this.ui.getDivOffset(obj);
                    this.data.multiArr.push(offset);
                }
            }

            var deltaY = this.ui.gridToLayerY(beat) - this.ui.gridToLayerY(this.data.currBeat);  //y差值
            var deltaX = (beat[3] - this.data.currBeat[3]) * this.ui.scaleW;
            this.data.currBeat = beat;

            var divs = this.data.multiNote;
            var arr = this.data.multiArr;
            //尝试移动一次看整体在没在范围内
            for (var i = 0; i < divs.size(); i++) {
                var resultX = this.ui.alignToX(arr[i].left + deltaX);
                if(resultX < 0){
                    return;
                }
            }
            for (var i = 0; i < divs.size(); i++) {
                var obj = divs.eq(i);
                arr[i].bottom += deltaY;
                arr[i].left = this.ui.alignToX(arr[i].left + deltaX);
                obj.css({
                    bottom: arr[i].bottom,
                    left: arr[i].left
                });
            }

            if (divs.size() == 1) {
                this.checkSelectTip(divs);
            }
        }
        return;
    }

    this._onMouseMove(pos);
};

GridEdit.prototype.onMouseUp = function (pos) {
    //复用了edit的mouseUp, x值不会被处理, 这里提前处理x
    if ((this.intent & this.Intent_Drag) > 0 && this.data.multiNote) {
        var gridPos = this.ui.mouseToGridOffset(pos);
        var deltaX = gridPos[3] - this.data.startBeat[3];
        //拖动模式的最后, 要移除编辑区域以外的note
        var divs = this.data.multiNote;
        for (var i = 0; i < divs.size(); i++) {
            var obj = divs.eq(i);
            var note = this.ui.manager.getNote(+obj.data("tag"));
            note.x += deltaX;
        }
    }
    //不允许在spinner区间放note
    if((this.intent & this.Intent_Add_Normal) > 0){
        if($(window.event.target).hasClass("spinner_mask")){
            notify.addNotify({msg : config.i18n("catch05")});
            return;
        }
    }

    var virtualNote = this.data ? this.data.virtualNote : null;
    var _virtualNote = virtualNote;
    var lastIntent = this.intent;
    var multiNote = this.data ? this.data.multiNote : null;
    var isNoteSelected = !!$(this.ui.note).children(".curr").length;
    if((lastIntent & this.Intent_Add_Normal) > 0){
        if(_virtualNote.x < 0){
            return;
        }
    }
    this._onMouseUp(pos);
    this.checkSelectTip();


    if((lastIntent & this.Intent_Add_Normal) > 0 && !isNoteSelected){
        var noteDiv = this.ui.getNoteDiv(virtualNote.id);
        if((lastIntent & this.Intent_Add_Catch_Hold) > 0){
            if(this.lastNote){
                this.editDrawHold(virtualNote);
            }
            noteDiv.addClass("hold_node");
            if (this.currHoldIdx >= this.MAX_HOLD_NOTES - 1) {
                this.endStepEdit();
                _virtualNote = null;
            }else{
                this.intent = this.Intent_Add_Catch_Hold;
            }
        }else if((lastIntent & this.Intent_Add_Catch_Rain) > 0){
            if(this.lastNote){
                this.editDrawRain(virtualNote);
                _virtualNote = null;
            }else{
                this.intent = this.Intent_Add_Catch_Rain;
            }
            virtualNote.type = this.ui.TYPE_RAIN;
            noteDiv.addClass("spinner_anchor");
        }
        if($("#tool_hold").hasClass("press") || $("#tool_rain").hasClass("press")){
            // 如果有选择的话 第一次点击是取消选择
            this.lastNote = _virtualNote;
        }
    }else if((lastIntent & this.Intent_Drag) > 0){
    	this.updateHoldNotes(multiNote);
    }
};

/**
 * 处理移动后hold和spinner的样式
 * @param notes
 */
GridEdit.prototype.updateHoldNotes = function(notes){
    if(!notes){
        return;
    }
    var prevNode,nextNode,node,id,note;
    for(var i=0;i<notes.length;i++){
        note = $(notes[i]);
        id = +note.attr("data-tag");
        node = this.ui.manager.getNote(id);
        if(note.hasClass("hold_node")){
            if(node.next > 0){
                nextNode = this.ui.manager.getNote(node.next);
                this.ui.getNoteHoldLineDiv(node, nextNode, true);
            }
            if(node.prev > 0){
                prevNode = this.ui.manager.getNote(node.prev);
                prevNode.endx = node.x;
                prevNode._endbeat = node.beat;
                this.ui.getNoteHoldLineDiv(prevNode, node, true);
            }
        }else if(note.hasClass("spinner_anchor")){
            if(node.next > 0){
                prevNode = node;
                nextNode = this.ui.manager.getNote(node.next);
            }else if(node.prev > 0){
                nextNode = node;
                prevNode = this.ui.manager.getNote(node.prev);
                prevNode._endbeat = node.beat;
            }
            this.ui.getSpinnerMaskDiv(prevNode, nextNode, true);
        }
    }
};

GridEdit.prototype.editDrawRain = function(curr){
    var last = this.lastNote;
    last._endbeat = curr.beat;
    last.next = curr.id;
    curr.prev = last.id;
    curr.next = -1;
    this.ui.note.append(this.ui.getSpinnerMaskDiv(last, curr));
    this.lastNote = null;
};

/**
 * 编辑模式下绘制hold串
 */
GridEdit.prototype.editDrawHold = function (curr) {
    this.currHoldIdx++;
    var lineDiv = this.ui.getNoteHoldLineDiv(this.lastNote, curr);
    $(lineDiv).appendTo(this.ui.note);
    //用当前note的位置作为上一个note的终点
    this.lastNote.endx = curr.x;
    this.lastNote._endbeat = curr.beat;
    this.lastNote.next = curr.id;
    curr.prev = this.lastNote.id;
    curr.next = -1;
};

GridEdit.prototype.endStepEdit = function(){
    this.currHoldIdx = 0;
    //如果正在绘制spinner 按esc要把上一个点也删了
    if($("#tool_rain").hasClass("press") && this.lastNote){
        this.ui._deleteNote(this.lastNote);
    }
    this.intent = 0;
    this.lastNote = null;
};

GridEdit.prototype.checkSelectTip = function (notes) {
    if (!notes) {
        notes = this.ui.note.find('.curr');
    }
    this.ui.vert.hide();
    this.ui.range.hide();

    if (notes.size() == 1) {
        var left = parseFloat(notes.css('left'));
        this.ui.vert.css('left', left).show();
    } else if (notes.size() == 2) {
        var note1 = notes.eq(0);
        var note2 = notes.eq(1);
        //bottom较小那个为主note
        var bottom1 = parseFloat(note1.css('bottom'));
        var bottom2 = parseFloat(note2.css('bottom'));
        var left = 0;
        if (bottom1 < bottom2) {
            left = parseFloat(note1.css('left'));
        } else {
            left = parseFloat(note2.css('left'));
        }
        this.ui.range.css('left', left);
        var _note1 = this.ui.manager.getNote(+note1.data('tag'));
        var _note2 = this.ui.manager.getNote(+note2.data('tag'));
        var time1 = timing.beatToTime(_note1.beat);
        var time2 = timing.beatToTime(_note2.beat);

        var delta = Math.abs(time1 - time2);
        //可能时间点重合了, 或者mapper该吃药
        if (delta < 10) {
            return;
        }
        //t时间能可运动的范围等于t像素 * grid缩放
        //实际范围还要加上半个托盘宽度
        //dash范围是normal的2倍
        this.ui.updateRange(delta * this.ui.scaleW);
        this.ui.range.show();
    }
};

/**
 * 在切换工具时结束当前的rain或者hold的绘制
 */
GridEdit.prototype.endHoldRainDrawing = function(){
    if((this.intent & this.Intent_Add_Catch_Hold) > 0 || (this.intent & this.Intent_Add_Catch_Rain) > 0){
        this.endStepEdit();
    }
    this.lastNote = null;
    this.intent = 0;
};

/**
 * 检查在给定区间内是否有note
 * @param startBeat
 * @param endBeat
 */
GridEdit.prototype.hasNoteInRange = function(startBeat, endBeat){
    var notes = this.ui.manager.getNotes();
    for(var i=0;i<notes.length;i++){
        var note = notes[i];
        if(frac.compare(note.beat, startBeat) > 0 && frac.compare(endBeat, note.beat) > 0){
            return true;
        }
        if(note.endbeat){
            if(frac.compare(note.endbeat, startBeat) > 0 && frac.compare(endBeat, note.endbeat) > 0){
                return true;
            }
        }
    }
    return false;
};

/**
 * 检查hold是否跨越了rain
 * @param startBeat
 * @param endBeat
 */
GridEdit.prototype.isHoldCrossRain = function(startBeat, endBeat){

};
module.exports = GridEdit;